<template>
  <div style="padding: 40px">
    <el-card class="box-card" :body-style="{height: '100%',position: 'relative'}">
      <div slot="header">
        <router-link :to="{path: '/modules'}">
          <el-button type="primary" size="small">返回</el-button>
        </router-link>
        <el-button type="primary" size="small" @click="saveModal">保存</el-button>

        <!--打开文件-->
        <el-upload action class="upload-demo" :before-upload="openBpmn">
          <el-button icon="el-icon-folder-opened" type="primary" size="small"/>
        </el-upload>
        <el-button icon="el-icon-circle-plus" type="primary" size="small" @click="newDiagram"/>
        <el-button icon="el-icon-download" type="primary" size="small" @click="downloadXML"/>
        <el-button icon="el-icon-picture" type="primary" size="small" @click="downloadSVG"/>
        <a ref="downloadLink" hidden/>
      </div>
      <div :style="{height: 'calc(100% - 100px)'}">
        <!-- 创建一个canvas画布 npmn-js是通过canvas实现绘图的，并设置ref让vue获取到element -->
        <div ref="canvas" class="bpmn-canvas"/>
        <!-- 工具栏显示的地方 -->
        <div id="js-properties-panel" class="bpmn-js-properties-panel"/>
      </div>
    </el-card>
  </div>
</template>
<script>// 引入相关的依赖
import BpmnModeler from 'bpmn-js/lib/Modeler'
// 工具栏相关
import propertiesProviderModule from 'bpmn-js-properties-panel/lib/provider/camunda'
import propertiesPanelModule from 'bpmn-js-properties-panel'
import camundaModdleDescriptor from 'camunda-bpmn-moddle/resources/camunda'
import customTranslate from './locals/customTranslate'
import { templateXml, addModel } from '@/api/template'
import { BPMN_TEMPLATE, downloadSVG, downloadXML } from './bpmnApi'

export default {
  name: 'BpmnModeler',
  data() {
    return {
      bpmnModeler: null,
      canvas: null,
      bpmnTemplate: BPMN_TEMPLATE,
      modelId: this.$route.query.modelId || '',
      processId: this.$route.query.processId || '',
      isModify: this.$route.query.isModify || false
    }
  },
  mounted() {
    this.init()
  },
  methods: {
    getXmlTemplate(id) {
      return new Promise((resolve, reject) => {
        templateXml(this.modelId).then(response => {
          this.bpmnTemplate = response.data ? response.data : BPMN_TEMPLATE
          resolve()
        })
      })
    },
    downloadXML,
    downloadSVG,
    newDiagram() {
      this.createNewDiagram(this.bpmnTemplate)
    },

    openBpmn(file) {
      const reader = new FileReader()
      // 读取File对象中的文本信息，编码格式为UTF-8
      reader.readAsText(file, 'utf-8')
      reader.onload = () => {
        // 读取完毕后将文本信息导入到Bpmn建模器
        this.createNewDiagram(reader.result)
      }
      return false
    },

    async init() {
      // 获取画布 element
      this.canvas = this.$refs.canvas
      // 创建Bpmn对象
      this.bpmnModeler = new BpmnModeler({
        // 设置bpmn的绘图容器为上门获取的画布 element
        container: this.canvas,
        width: '100%',
        height: '750px',
        // 加入工具栏支持
        propertiesPanel: {
          parent: '#js-properties-panel'
        },
        additionalModules: [
          propertiesProviderModule, propertiesPanelModule,
          {
            translate: ['value', customTranslate]
          }
        ],
        moddleExtensions: {
          camunda: camundaModdleDescriptor
        }
      })

      await new Promise((resolve, reject) => {
        this.modelId = this.$route.query.modelId
        this.processId = this.$route.query.processId
        this.isModify = this.$route.query.isModify
        resolve()
      })
      if (this.isModify) {
        // 请求后台数据
        await this.getXmlTemplate()
      }
      this.$nextTick(() => {
        this.createNewDiagram(this.bpmnTemplate)
      })
    },
    async createNewDiagram(bpmn) {
      // 将字符串转换成图显示出来;
      this.bpmnModeler.importXML(bpmn, err => {
        if (err) {
          this.$message.error('打开模型出错,请确认该模型符合Bpmn2.0规范')
        }
      })
    },
    saveModal() {
      this.bpmnModeler.saveXML({ format: true }, (err, xml) => {
        if (!err) {
          addModel({
            processId: this.processId,
            xml: xml
          }).then(response => {
            this.$message.success('保存成功')
          })
        }
      })
    }
  }
}
</script>
<style scoped lang="scss">
  .bpmn-canvas {
    width: 100%;
    height: 100vh;

    .bjs-container {
      a {
        visibility: hidden;
      }
    }
  }

  .action {
    position: fixed;
    bottom: 10px;
    left: 230px;
    display: flex;
  }

  .upload-demo {
    display: inline-block;
  }

  .bpmn-js-properties-panel {
    position: absolute;
    top: 0px;
    right: 0px;
    width: 300px;
  }

</style>
